package org.mcflier.appuntamento.core.logger;

import java.io.IOException;
import java.util.Properties;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import org.mcflier.appuntamento.core.exception.PropertiesException;
import org.mcflier.appuntamento.core.properties.PropertiesManager;

public class LoggerManager {

	private static LoggerManager instance;

	static{
		instance = null;
	}

	public static LoggerManager getInstance() {
		if(instance == null)
			instance = new LoggerManager();

		return instance;
	}

	private static final String LOGGER_LEVEL_TAG = "logger_level";
	private static final String LOGGER_USE_LOG_TAG = "use_filelog";
	private static final String LOGGER_FILELOG_PATH_TAG = "filelog_path";

	private Properties properties;
	private Logger rootLogger;

	private LoggerManager() {
		PropertiesManager propertiesManager;
		this.properties = null;
		try {
			propertiesManager = PropertiesManager.getInstance();
			this.properties = propertiesManager.getProperties();
		} catch (PropertiesException e) {

		}

		this.rootLogger = this.initiateRootLogger(this.getClass().getName());
	}

	private void defaultInit(){
		Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
		logger.setLevel(Level.INFO);
	}

	private Logger initiateRootLogger(String name){
		Logger logger = Logger.getLogger(name);
		try {
			int option = Integer.parseInt(this.properties.getProperty(LOGGER_LEVEL_TAG));
			switch(option){
				case 1:
					logger.setLevel(Level.SEVERE);
					break;
				case 2:
					logger.setLevel(Level.WARNING);
					break;
				case 3:
					logger.setLevel(Level.INFO);
					break;
				case 4:
					logger.setLevel(Level.CONFIG);
					break;
				case 5:
					logger.setLevel(Level.FINE);
					break;
				case 6:
					logger.setLevel(Level.FINER);
					break;
				case 7:
					logger.setLevel(Level.FINEST);
					break;
				case 8:
					logger.setLevel(Level.ALL);
					break;
				case 9:
					logger.setLevel(Level.OFF);
					break;
				default:{
					logger.setLevel(Level.INFO);
					logger.warning("Logger properties file: Logger level not valid. Correct values: 1 severe, 2 warning, 3 info, 4 config, 5 fine, 6 finer, 7 finest, 8 ALL, 9 OFF");
				}
			}

			if(Boolean.valueOf(this.properties.getProperty(LOGGER_USE_LOG_TAG, "false"))){
				String filelogpath = this.properties.getProperty(LOGGER_FILELOG_PATH_TAG);
				if(filelogpath==null) logger.warning("Logger properties file: Use filelog set true but filelog path not specified");
				else{
					FileHandler handler;
					handler = new FileHandler(filelogpath);
					handler.setFormatter(new SimpleFormatter());
					logger.addHandler(handler);
				}
			}

			logger.info("Logger configured");

			return logger;
		} catch (SecurityException e) {
			this.defaultInit();
			logger = this.getLogger(name);
			logger.warning("Error loading logger properties. Loaded default properties");
			logger.warning(e.getMessage());
		} catch (IOException e) {
			this.defaultInit();
			logger = this.getLogger(name);
			logger.warning("Error loading logger properties. Loaded default properties");
			logger.warning(e.getMessage());
		} catch (NullPointerException e) {
			this.defaultInit();
			logger = this.getLogger(name);
			logger.warning("Error loading logger properties. Loaded default properties");
			logger.warning(e.getMessage());
		}
		return logger;
	}

	public Logger getLogger(String name){
		Logger logger = Logger.getLogger(name);
		logger.setParent(this.rootLogger);
		return logger;
	}
}
